
package com.j256.ormlite.stmt;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.j256.ormlite.dao.CloseableIterator;
import com.j256.ormlite.dao.GenericRawResults;
import com.j256.ormlite.dao.ObjectCache;
import com.j256.ormlite.support.CompiledStatement;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.support.DatabaseConnection;

/**
 * Handler for our raw results objects which does the conversion for various
 * different results: String[], Object[], and user defined <T>.
 * 
 * @author graywatson
 */
public class RawResultsImpl<T> implements GenericRawResults<T> {

    private SelectIterator<T, Void> iterator;
    private final String[] columnNames;

    public RawResultsImpl(ConnectionSource connectionSource, DatabaseConnection connection,
            String query, Class<?> clazz, CompiledStatement compiledStmt, String[] columnNames,
            GenericRowMapper<T> rowMapper, ObjectCache objectCache) throws SQLException {
        iterator = new SelectIterator<T, Void>(clazz, null, rowMapper, connectionSource,
                connection, compiledStmt, query, objectCache);
        this.columnNames = columnNames;
    }

    @Override
    public int getNumberColumns() {
        return columnNames.length;
    }

    @Override
    public String[] getColumnNames() {
        return columnNames;
    }

    @Override
    public List<T> getResults() throws SQLException {
        List<T> results = new ArrayList<T>();
        try {
            while (iterator.hasNext()) {
                results.add(iterator.next());
            }
            return results;
        } finally {
            iterator.close();
        }
    }

    @Override
    public T getFirstResult() throws SQLException {
        try {
            if (iterator.hasNextThrow()) {
                return iterator.nextThrow();
            } else {
                return null;
            }
        } finally {
            close();
        }
    }

    @Override
    public CloseableIterator<T> iterator() {
        return iterator;
    }

    @Override
    public CloseableIterator<T> closeableIterator() {
        return iterator;
    }

    @Override
    public void close() throws SQLException {
        if (iterator != null) {
            iterator.close();
            iterator = null;
        }
    }
}
